package com.chagee.store.operation.server.facade.provider;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chagee.base.utils.SoaResponse;
import com.chagee.base.utils.SoaUtil;
import com.chagee.store.operation.api.bo.*;
import com.chagee.store.operation.api.enums.*;
import com.chagee.store.operation.api.enums.StoreWorkOrderStatusEnum;
import com.chagee.store.operation.api.request.OrderAppealCallbackRequest;
import com.chagee.store.operation.api.request.TaskAppealCallbackRequest;
import com.chagee.store.operation.api.service.ITSelfOperationAppealApi;
import com.chagee.store.operation.common.constant.CommonConstant;
import com.chagee.store.operation.common.enums.MassageTypeEnum;
import com.chagee.store.operation.server.entity.*;
import com.chagee.store.operation.server.event.service.*;
import com.chagee.store.operation.server.model.bo.OrderAppealRecordBO;
import com.chagee.store.operation.server.service.base.StoreBaseService;
import com.chagee.store.operation.server.service.biz.OperateRecordBizService;
import com.chagee.store.operation.server.service.biz.StoreSettlementBizService;
import com.chagee.store.operation.server.service.third.EventThirdService;
import com.chagee.store.operation.server.service.third.FeiShuSendService;
import com.chagee.storeManagement.api.event.enums.*;
import com.chagee.storeManagement.api.event.request.OperateRecordRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.*;
import java.util.*;

/**
 * @Author : hk
 * @Date : 2025/2/8
 */

@Service
@Slf4j
@RequiredArgsConstructor
public class SelfOperationAppealApiImpl implements ITSelfOperationAppealApi {


	@Resource
	private WorkOrderBaseService workOrderBaseService;

	@Resource
	private WorkOrderReceiverBaseService workOrderReceiverBaseService;

	@Resource
	private TaskExecutionBaseService taskExecutionBaseService;

	@Resource
	private StoreSettlementBaseService storeSettlementBaseService;

	@Resource
	private StoreBaseService storeBaseService;

	@Value("${settlement.storeTag}")
	private String storeTag;

	@Resource
	private EventThirdService eventThirdService;

	@Value("${settlement.supplierVerifyTimeout:259200}")
	private Integer supplierVerifyTimeout;

	@Resource
	private StoreSettlementBizService storeSettlementBizService;

	@Resource
	private OperateRecordBizService operateRecordBizService;

	@Resource
	private FeiShuSendService feiShuSendService;

	@Override
	public SoaResponse<Boolean, Void> taskAppeal(TaskAppealCallbackRequest request) {
		log.info("taskAppeal_TimeOut:{}", request.getWorkOrderNumber());
		LambdaQueryWrapper<WorkOrderDO> wrapper = new LambdaQueryWrapper();
		wrapper.eq(WorkOrderDO::getWorkOrderNumber, request.getWorkOrderNumber());
		wrapper.eq(WorkOrderDO::getDeleteFlag, NumberUtils.INTEGER_ZERO);
		WorkOrderDO workOrderDO = workOrderBaseService.getOne(wrapper);

		List<TaskExecutionDO> taskList = taskExecutionBaseService.queryTaskByWorkOrderNumber(workOrderDO.getWorkOrderNumber(), AppealStatusEnum.PENDING_PROCESSING.getType());
		// 工单下未处理申诉任务变更为已驳回状态
		if (CollectionUtil.isNotEmpty(taskList)) {
			taskList.forEach(s-> {
				AppealExtraVO appealExtraVO = new AppealExtraVO();
				if (StringUtils.isNotBlank(s.getExtra())) {
					appealExtraVO = JSON.parseObject(s.getExtra(), AppealExtraVO.class);
				}
				appealExtraVO.setHandleAppealReason(CommonConstant.HANDLE_APPEAL_REASON);
				s.setExtra(JSONObject.toJSONString(appealExtraVO));
				s.setAppealStatus(AppealStatusEnum.REJECTED.getType());
				taskExecutionBaseService.updateTaskAppealStatus(s, AppealStatusEnum.REJECTED.getType());

				feiShuSendService.sendTaskApprovalFeiShuMessage(workOrderDO, s);

				// 操作日志
				OperateRecordRequest operateRecordRequest = new OperateRecordRequest();
				operateRecordRequest.setStoreNo(workOrderDO.getWorkOrderNumber());

				OrderAppealRecordBO updateBefore = new OrderAppealRecordBO();
				updateBefore.setDocumentStatus(StoreWorkOrderStatusEnum.getByType(workOrderDO.getDocumentStatus()).getDesc());
				operateRecordRequest.setUpdateBefore(JSON.toJSONString(updateBefore));

				OrderAppealRecordBO updateData = new OrderAppealRecordBO();
				updateData.setRecordName(RecordTypeEnum.APPROVAL_TASK_APPEAL.getDesc());
				updateData.setStoreTaskRelationId(s.getStoreTaskRelationId());
				updateData.setTaskName(s.getTaskName());
				updateData.setApproveAppealReason(CommonConstant.HANDLE_APPEAL_REASON);
				updateData.setAppealStatus(AppealStatusEnum.REJECTED.getDesc());
				operateRecordRequest.setUpdateData(JSON.toJSONString(updateData));

				operateRecordRequest.setUpdateFrom(OptResourceEnum.STORE_SYS.getDesc());
				operateRecordRequest.setUpdateFromCode(StringUtils.EMPTY);
				operateRecordBizService.updateOptRecord(operateRecordRequest);
			});
		}
		if (workOrderDO.getDocumentStatus().equals(StoreWorkOrderStatusEnum.IN_APPEAL.getType())) {
			StoreWorkOrderStatusEnum status = StoreWorkOrderStatusEnum.COMPLETED;
			workOrderDO.setDocumentStatus(status.getType());
			workOrderBaseService.update(workOrderDO);
			List<WorkOrderReceiverDO> workOrderReceiverDOS = workOrderReceiverBaseService.queryOrderByWorkOrderNumber(workOrderDO.getWorkOrderNumber());
			if (CollectionUtil.isNotEmpty(workOrderReceiverDOS)) {
				workOrderReceiverBaseService.batchUpdateOrderStatus(workOrderReceiverDOS, status.getType(), StringUtils.EMPTY);
			}
		}

		return SoaUtil.ok(true);
	}

	@Override
	public SoaResponse<Boolean, Void> orderAppeal(OrderAppealCallbackRequest request) {
		log.info("orderAppeal_TimeOut:{}", request.getWorkOrderNumber());
		LambdaQueryWrapper<WorkOrderDO> wrapper = new LambdaQueryWrapper();
		wrapper.eq(WorkOrderDO::getWorkOrderNumber, request.getWorkOrderNumber());
		wrapper.eq(WorkOrderDO::getDeleteFlag, NumberUtils.INTEGER_ZERO);
		WorkOrderDO workOrderDO = workOrderBaseService.getOne(wrapper);

		if (workOrderDO.getDocumentStatus().equals(StoreWorkOrderStatusEnum.EXPIRED_APPEAL.getType())) {
			workOrderDO.setAppealResult(OrderAppealStatusEnum.N.getType());
			workOrderDO.setDocumentStatus(request.getDocumentStatus());
			OrderExtJsonBO extJsonBO = new OrderExtJsonBO();
			if (StringUtils.isNotBlank(workOrderDO.getExtra())) {
				extJsonBO = JSON.parseObject(workOrderDO.getExtra(), new TypeReference<OrderExtJsonBO>() {
				});
			}
			extJsonBO.setHandleAppealReason(CommonConstant.HANDLE_APPEAL_REASON);
			workOrderDO.setExtra(JSONObject.toJSON(extJsonBO).toString());
			workOrderBaseService.update(workOrderDO);
			List<WorkOrderReceiverDO> workOrderReceiverDOS = workOrderReceiverBaseService.queryOrderByWorkOrderNumber(workOrderDO.getWorkOrderNumber());
			if (CollectionUtil.isNotEmpty(workOrderReceiverDOS)) {
				workOrderReceiverBaseService.batchUpdateOrderStatus(workOrderReceiverDOS, request.getDocumentStatus(), StringUtils.EMPTY);
			}

			//超时自动驳回通知
			feiShuSendService.sendOrderHandleFeiShuMsg(workOrderDO);

			// 操作日志
			OperateRecordRequest operateRecordRequest = new OperateRecordRequest();
			operateRecordRequest.setStoreNo(request.getWorkOrderNumber());

			OrderAppealRecordBO updateBefore = new OrderAppealRecordBO();
			updateBefore.setDocumentStatus(StoreWorkOrderStatusEnum.EXPIRED_APPEAL.getDesc());
			operateRecordRequest.setUpdateBefore(JSON.toJSONString(updateBefore));

			OrderAppealRecordBO updateData = new OrderAppealRecordBO();
			updateData.setRecordName(RecordTypeEnum.APPROVAL_ORDER_APPEAL.getDesc());
			updateData.setDocumentStatus(StoreWorkOrderStatusEnum.getByType(workOrderDO.getDocumentStatus()).getDesc());
			updateData.setApproveAppealReason(CommonConstant.HANDLE_APPEAL_REASON);
			updateData.setAppealStatus(OrderAppealStatusEnum.N.getDesc());
			operateRecordRequest.setUpdateData(JSON.toJSONString(updateData));

			operateRecordRequest.setUpdateFrom(OptResourceEnum.STORE_SYS.getDesc());
			operateRecordRequest.setUpdateFromCode(StringUtils.EMPTY);

			operateRecordBizService.updateOptRecord(operateRecordRequest);
		}

		return SoaUtil.ok(true);
	}

	/**
	 * 待门店确认超时
	 * @param settlementNo
	 * @return
	 */
	@Override
	public SoaResponse<Boolean, Void> waitStoreVerifyTimeOut(String settlementNo) {
		log.info("storeVerifyTimeOut_settlementNo:{}", settlementNo);
		StoreSettlementDO storeSettlementDO = storeSettlementBaseService.querySettlement(settlementNo);

		if (Objects.nonNull(storeSettlementDO)) {
			if (StringUtils.equals(SettlementStatusEnum.WAIT_STORE_VERIFY.getType(), storeSettlementDO.getDocumentStatus())) {
				//加盟店
				if (StringUtils.equals(StoreCategoryEnum.JM.getType(), storeSettlementDO.getStoreCategory())) {
					List<StoreDO> storeDOS = storeBaseService.batchSelectStoreList(CollectionUtil.newArrayList(storeSettlementDO.getStoreNo()));
					log.info("storeVerifyTimeOut_storeTag:{}", JSONObject.toJSONString(storeDOS));
					Optional<StoreDO> op = storeDOS.stream().findFirst();
					if (op.isPresent()) {
						StoreDO storeDO = op.get();

						NeedInvoiceEnum ifNeedInvoice = NeedInvoiceEnum.NOT_NEED;
						if (StringUtils.isNotBlank(storeDO.getTag())) {
							TagJsonBO tagJsonBO = JSONObject.parseObject(storeDO.getTag(), TagJsonBO.class);
							Set<String> tagCodes = tagJsonBO.getTagCodes();
							if (tagCodes.contains(storeTag)) {
								ifNeedInvoice = NeedInvoiceEnum.NEED;
							}
						}
						storeSettlementDO.setPushInvoiceFlag(ifNeedInvoice.getType());
					}
				}
				storeSettlementBaseService.update(SettlementStatusEnum.WAIT_SUPPLIER_VERIFY.getType(), StringUtils.EMPTY, storeSettlementDO);

				try {
					Long expiredDate = System.currentTimeMillis() + (supplierVerifyTimeout * 1000L);
					LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(expiredDate), ZoneId.systemDefault());

					eventThirdService.registerDefaultTimerEvent(storeSettlementDO.getSettlementNo(), null, dateTime, EventTypeEnum.WAIT_SUPPLIER_VERIFY_TIME_OUT);
				} catch (Exception e) {
					log.error("结算单待供应商确认注册失败", e);
				}
			}
		}

		return SoaUtil.ok(true);
	}

	/**
	 * 待供应商确认超时
	 * @param settlementNo
	 * @return
	 */
	@Override
	public SoaResponse<Boolean, Void> waitSupplierVerifyTimeOut(String settlementNo) {
		log.info("SupplierVerifyTimeOut_settlementNo:{}", settlementNo);
		StoreSettlementDO storeSettlementDO = storeSettlementBaseService.querySettlement(settlementNo);

		if (Objects.nonNull(storeSettlementDO)) {
			if (StringUtils.equals(SettlementStatusEnum.WAIT_SUPPLIER_VERIFY.getType(), storeSettlementDO.getDocumentStatus())) {

				SettlementStatusEnum status = SettlementStatusEnum.SUBMIT_INVOICE;
				//加盟店  (若选择不需要上传发票或者 没有选择<超时>)
				if (StringUtils.equals(StoreCategoryEnum.JM.getType(), storeSettlementDO.getStoreCategory()) &&
					(StringUtils.equals(NeedInvoiceEnum.NOT_NEED.getType(), storeSettlementDO.getPushInvoiceFlag()) || Objects.isNull(storeSettlementDO.getPushInvoiceFlag()))) {
					status = SettlementStatusEnum.WAIT_PAY;
					storeSettlementDO.setWaitPayTime(LocalDateTime.now());
				}

				if (storeSettlementDO.getPayMoney().compareTo(BigDecimal.ZERO) <= 0) {
					status = SettlementStatusEnum.COMPLETE;
				}
				storeSettlementBaseService.update(status.getType(), StringUtils.EMPTY, storeSettlementDO);
			}
		}

		return SoaUtil.ok(true);
	}



}
